package com.example.myblog.service;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

/**
 * 阿里云OSS文件上传服务
 */
@Service
public class OssService {

    @Value("${aliyun.oss.endpoint}")
    private String endpoint;

    @Value("${aliyun.oss.accessKeyId}")
    private String accessKeyId;

    @Value("${aliyun.oss.accessKeySecret}")
    private String accessKeySecret;

    @Value("${aliyun.oss.bucketName}")
    private String bucketName;

    @Value("${aliyun.oss.urlPrefix}")
    private String urlPrefix;

    /**
     * 上传文件到OSS
     * 
     * @param file 要上传的文件
     * @return 上传成功后的文件访问URL
     */
    public String uploadFile(MultipartFile file) {
        // 生成文件名
        String originalFilename = file.getOriginalFilename();
        String fileExtension = "";
        if (originalFilename != null && originalFilename.contains(".")) {
            fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
        }
        
        // 使用UUID和日期生成唯一文件名
        String uuid = UUID.randomUUID().toString().replace("-", "");
        String datePath = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
        String fileName = "images/" + datePath + "/" + uuid + fileExtension;
        
        // 创建OSSClient实例
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        
        try {
            InputStream inputStream = file.getInputStream();
            
            // 创建上传Object的元数据
            ObjectMetadata metadata = new ObjectMetadata();
            // 设置Content-Type
            metadata.setContentType(getContentType(fileExtension));
            
            // 创建PutObjectRequest对象
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileName, inputStream, metadata);
            
            // 上传文件
            ossClient.putObject(putObjectRequest);
            
            // 关闭OSSClient
            ossClient.shutdown();
            
            // 返回文件访问URL
            return urlPrefix + fileName;
            
        } catch (IOException e) {
            throw new RuntimeException("文件上传失败: " + e.getMessage());
        }
    }
    
    /**
     * 从OSS删除文件
     * 
     * @param fileUrl 文件的完整URL
     */
    public void deleteFile(String fileUrl) {
        if (fileUrl == null || !fileUrl.startsWith(urlPrefix)) {
            return; // 不是OSS文件，无需删除
        }
        
        // 从URL中提取文件路径
        String fileName = fileUrl.substring(urlPrefix.length());
        
        // 创建OSSClient实例
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        
        try {
            // 删除文件
            ossClient.deleteObject(bucketName, fileName);
        } catch (Exception e) {
            // 删除失败时记录日志，但不抛出异常，避免影响业务流程
            System.err.println("删除OSS文件失败: " + fileName + ", 错误: " + e.getMessage());
        } finally {
            // 关闭OSSClient
            ossClient.shutdown();
        }
    }
    
    /**
     * 根据文件扩展名获取对应的Content-Type
     * 
     * @param fileExtension 文件扩展名
     * @return 对应的Content-Type
     */
    private String getContentType(String fileExtension) {
        if (fileExtension == null) {
            return "application/octet-stream";
        }
        
        fileExtension = fileExtension.toLowerCase();
        
        switch (fileExtension) {
            case ".jpg":
            case ".jpeg":
                return "image/jpeg";
            case ".png":
                return "image/png";
            case ".gif":
                return "image/gif";
            case ".bmp":
                return "image/bmp";
            case ".webp":
                return "image/webp";
            default:
                return "application/octet-stream";
        }
    }
    
    /**
     * 将OSS中的文件按URL读取并写入到输出流（用于预览端点）。
     */
    public void streamFileTo(String fileUrl, java.io.OutputStream output) throws IOException {
        if (fileUrl == null || !fileUrl.startsWith(urlPrefix)) {
            throw new IOException("不是受管的OSS文件URL");
        }
        String objectKey = fileUrl.substring(urlPrefix.length());
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        com.aliyun.oss.model.OSSObject ossObject = null;
        try {
            ossObject = ossClient.getObject(bucketName, objectKey);
            try (InputStream in = ossObject.getObjectContent()) {
                byte[] buffer = new byte[8192];
                int len;
                while ((len = in.read(buffer)) != -1) {
                    output.write(buffer, 0, len);
                }
                output.flush();
            }
        } finally {
            try { if (ossObject != null) ossObject.close(); } catch (Exception ignored) {}
            try { ossClient.shutdown(); } catch (Exception ignored) {}
        }
    }

    /**
     * 简单的根据扩展名判断Content-Type（预览时兜底）。
     */
    public String detectContentTypeByFilename(String fileName) {
        if (fileName == null) return "application/octet-stream";
        String ext = fileName.contains(".") ? fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase() : "";
        switch (ext) {
            case "jpg": case "jpeg": return "image/jpeg";
            case "png": return "image/png";
            case "gif": return "image/gif";
            case "bmp": return "image/bmp";
            case "webp": return "image/webp";
            case "svg": return "image/svg+xml";
            case "pdf": return "application/pdf";
            case "txt": return "text/plain";
            default: return "application/octet-stream";
        }
    }
}